package com.ruoyi.client.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.ruoyi.bookbus.domain.BookAddress;
import com.ruoyi.client.mapper.AddressMapper;
import com.ruoyi.client.pojo.form.AddressInsertForm;
import com.ruoyi.client.pojo.form.AddressUpdateForm;
import com.ruoyi.client.pojo.vo.AddressVo;
import com.ruoyi.client.service.AddressService;
import com.ruoyi.common.exception.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service("ClientAddressServiceImpl")
public class AddressServiceImpl implements AddressService {

    @Resource(name = "ClientAddressMapper") //注入指定命名的Bean
    private AddressMapper addressMapper;

    /**
     * 新增收货地址
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(AddressInsertForm form) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        Long userId = StpUtil.getLoginIdAsLong();

        BookAddress address = buildAddressForInsert(form, userId);

        boolean isDefault = Integer.valueOf(1).equals(address.getIsDefault());
        if (isDefault) {
            // 查询当前用户的默认地址，确保唯一性
            BookAddress defaultAddress = addressMapper.selectDefaultByUserId(userId);
            if (defaultAddress != null) {
                defaultAddress.setIsDefault(0); // 取消原默认地址
                int updateResult = addressMapper.update(defaultAddress); // 确保update参数类型匹配
                if (updateResult < 1) {
                    throw new ServiceException("更改默认地址失败");
                }
            }
        }
        // 持久化新增地址
        return addressMapper.insert(address) > 0;
    }


    /**
     * 删除收货地址
     */
    @Override
    public Boolean deleteById(Long addressId) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        if (addressId == null) {
            throw new ServiceException("地址ID不能为空");
        }
        // 验证地址是否存在且属于当前用户
        BookAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null || !address.getUserId().equals(StpUtil.getLoginIdAsLong())) {
            throw new ServiceException("无权操作此地址");
        }
        return addressMapper.deleteByPrimaryKey(addressId) > 0;
    }


    /**
     * 修改收货地址
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(AddressUpdateForm form) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        if (form.getId() == null) {
            throw new ServiceException("地址ID不能为空");
        }
        Long userId = StpUtil.getLoginIdAsLong();

        // 验证地址归属
        BookAddress existingAddress = addressMapper.selectByPrimaryKey(form.getId());
        if (existingAddress == null || !existingAddress.getUserId().equals(userId)) {
            throw new ServiceException("无权操作此地址");
        }

        BookAddress address = buildAddressForUpdate(form, userId);

        boolean isDefault = Integer.valueOf(1).equals(address.getIsDefault());
        if (isDefault) {
            BookAddress defaultAddress = addressMapper.selectDefaultByUserId(userId);
            // 若存在其他默认地址，取消其默认标记
            if (defaultAddress != null && !defaultAddress.getId().equals(address.getId())) {
                defaultAddress.setIsDefault(0);
                int updateResult = addressMapper.update(defaultAddress);
                if (updateResult < 1) {
                    throw new ServiceException("更改默认地址失败");
                }
            }
        }
        return addressMapper.update(address) > 0;
    }


    /**
     * 查询地址详情（实现类与接口返回类型保持一致）
     */
    @Override
    public BookAddress selectByPrimaryKey(Long addressId) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        if (addressId == null) {
            throw new ServiceException("地址ID不能为空");
        }
        BookAddress address = addressMapper.selectByPrimaryKey(addressId);
        if (address == null || !address.getUserId().equals(StpUtil.getLoginIdAsLong())) {
            throw new ServiceException("地址不存在或无权访问");
        }
        return address;
    }


    /**
     * 查询我的地址列表
     */
    @Override
    public List<AddressVo> selectListByMy() {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        Long userId = StpUtil.getLoginIdAsLong();
        List<BookAddress> addresses = addressMapper.selectListByUserId(userId);
        return addresses.stream()
                .map(this::toAddressVo)
                .collect(Collectors.toList());
    }


    /**
     * 查询地址详情VO
     */
    @Override
    public AddressVo selectDetailById(Long id) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        if (id == null) {
            throw new ServiceException("地址ID不能为空");
        }
        BookAddress address = addressMapper.selectByPrimaryKey(id);
        if (address == null || !address.getUserId().equals(StpUtil.getLoginIdAsLong())) {
            throw new ServiceException("地址不存在或无权访问");
        }
        return toAddressVo(address);
    }


    /**
     * 获取默认地址或指定地址
     */
    @Override
    public AddressVo getDefaultAddress(Long addressId) {
        if (!StpUtil.isLogin()) {
            throw new ServiceException("用户未登录");
        }
        Long userId = StpUtil.getLoginIdAsLong();
        BookAddress address;

        if (addressId == null) {
            address = addressMapper.selectDefaultByUserId(userId); // 查默认地址
        } else {
            address = addressMapper.selectByPrimaryKey(addressId); // 查指定地址
        }

        if (address == null || !address.getUserId().equals(userId)) {
            throw new ServiceException("地址不存在或无权访问");
        }

        return toAddressVo(address);
    }


    /**
     * 查询用户默认地址（实现类与接口返回类型保持一致）
     */
    @Override
    public BookAddress selectDefaultByUserId(Long userId) {
        if (userId == null || !StpUtil.isLogin() || !userId.equals(StpUtil.getLoginIdAsLong())) {
            throw new ServiceException("无权查询此用户地址");
        }
        return addressMapper.selectDefaultByUserId(userId);
    }

    private BookAddress buildAddressForInsert(AddressInsertForm form, Long userId) {
        BookAddress address = new BookAddress();
        address.setUserId(userId);
        address.setName(form.getName());
        address.setTel(form.getTel());
        address.setProvince(form.getProvince());
        address.setCity(form.getCity());
        address.setCounty(form.getCounty());
        address.setAddressDetail(form.getAddressDetail());
        address.setIsDefault(Boolean.TRUE.equals(form.getIsDefault()) ? 1 : 0);
        return address;
    }

    private BookAddress buildAddressForUpdate(AddressUpdateForm form, Long userId) {
        BookAddress address = new BookAddress();
        address.setId(form.getId());
        address.setUserId(userId);
        if (StringUtils.isNotBlank(form.getName())) {
            address.setName(form.getName());
        }
        if (StringUtils.isNotBlank(form.getTel())) {
            address.setTel(form.getTel());
        }
        if (StringUtils.isNotBlank(form.getProvince())) {
            address.setProvince(form.getProvince());
        }
        if (StringUtils.isNotBlank(form.getCity())) {
            address.setCity(form.getCity());
        }
        if (StringUtils.isNotBlank(form.getCounty())) {
            address.setCounty(form.getCounty());
        }
        if (StringUtils.isNotBlank(form.getAddressDetail())) {
            address.setAddressDetail(form.getAddressDetail());
        }
        address.setIsDefault(Boolean.TRUE.equals(form.getIsDefault()) ? 1 : 0);
        return address;
    }

    private AddressVo toAddressVo(BookAddress address) {
        AddressVo addressVo = new AddressVo();
        addressVo.setId(address.getId());
        addressVo.setUserId(address.getUserId());
        addressVo.setName(address.getName());
        addressVo.setTel(address.getTel());
        addressVo.setProvince(address.getProvince());
        addressVo.setCity(address.getCity());
        addressVo.setCounty(address.getCounty());
        addressVo.setAddressDetail(address.getAddressDetail());
        addressVo.setIsDefault(address.getIsDefault());
        return addressVo;
    }
}
